package stone.ast;

import java.util.List;

import stone.ClassInfo;
import stone.OptStoneObject.AccessException;
import stone.StoneException;
import ASTInterpreter.Environment;
import stone.OptClassInfo;
import ASTInterpreter.ArrayEnv;
import stone.OptStoneObject;

public class Dot extends Postfix {

	public Dot(List<ASTree> list) {
		super(list);
	}
	
	public String name() {
		return ((ASTLeaf)child(0)).token().getText();
	}

	/*
	@Override
	public Object eval(Environment env, Object value) {
		String member = name();
		if (value instanceof ClassInfo) {
			if ("new".equals(member)) {
				ClassInfo ci = (ClassInfo)value;
				NestedEnv e = new NestedEnv(ci.environment());
				StoneObject so = new StoneObject(e);
				e.putNew("this", so);
				initObject(ci, e);
				return so;
			}
		}
		else if (value instanceof StoneObject) {
			try {
				return ((StoneObject)value).read(member);
			} catch (AccessException e) {
			}
		}
		throw new StoneException("bad member access: " + member, this);
	}
	*/

	@Override
	public Object eval(Environment env, Object value) {
		String member = name();
		if (value instanceof OptClassInfo) {
			if ("new".equals(member)) {
				OptClassInfo ci = (OptClassInfo)value;
				ArrayEnv newEnv = new ArrayEnv(1, ci.environment());
				OptStoneObject so = new OptStoneObject(ci, ci.size());
				newEnv.put(0, 0, so);
				initObject(ci, newEnv);
				return so;
			}
		}
		else if (value instanceof OptStoneObject) {
			try {
				return ((OptStoneObject)value).read(member);
			}
			catch(AccessException e) {

			}
		}
		throw new StoneException("bad member access: " + member, this);
	}

	protected void initObject(ClassInfo ci, Environment env) {
		if (ci.superClass() != null) {
			initObject(ci.superClass(), env);
		}
		System.out.println(ci.body());
		ci.body().eval(env);
	}
	
	public String toString() {
		return "." + name();
	}

}
